package element.ast;

import element.base.Word;
import element.synt.Exp;
import element.synt.FuncRParams;
import element.synt.LVal;
import element.synt.UnaryExp;
import intermediate_representation.AssignRP;
import intermediate_representation.CallRP;
import symbal.Symbal;
import symbal.Vtype;
import table.InterCodeTable;
import table.Table;

public class PrimNode extends AstNode {
    private int primtype;
    private int number;
    private LVal lVal;
    private UnaryExp func;

    public PrimNode(int number) {
        this.primtype = 0;
        this.number = number;
    }

    public PrimNode(LVal lVal) {
        this.primtype = 1;
        this.lVal = lVal;
    }

    public PrimNode(UnaryExp func) {
        this.primtype = 2;
        this.func = func;
    }

    @Override
    public String tointerRP() {
        if (this.primtype == 0) {
            InterCodeTable.nowVar = String.valueOf(number);
        } else if (this.primtype == 1) {
            String tmp = lVal.toFormat();
            if (tmp.contains("[") && !tmp.contains("@")) {
                InterCodeTable.pushvar();
                AssignRP assignRP = new AssignRP(InterCodeTable.nowVar, tmp);
                InterCodeTable.addCode(assignRP);
            } else {
                InterCodeTable.nowVar = lVal.toFormat();
            }
        } else {
            String ident = func.findFirst().getContent();
            Symbal funcs = InterCodeTable.getSymbalTable().findSymbal(ident);
            ident = funcs.getMipsName();
            String res = "$void";
            CallRP callRP;
            if (funcs.getReturntype().equals(Vtype.INT)) {
                int nowindex = InterCodeTable.regindex;
                InterCodeTable.pushvar();
                String returns = InterCodeTable.nowVar;
                res = returns;
                callRP = new CallRP(returns, ident);
//                InterCodeTable.regindex = nowindex;
            } else {
                callRP = new CallRP(ident);
            }
            if (func.getNodes().get(2) instanceof FuncRParams) {
                FuncRParams funcRParams = (FuncRParams) func.getNodes().get(2);
                int expcount = funcRParams.getNodes().size() / 2 + 1;
                for (int i = 0; i < expcount; i++) {
                    Exp para = (Exp) funcRParams.getNodes().get(2 * i);
                    para.tointerRP();
                    callRP.addPara(InterCodeTable.nowVar);
                }
            }
            InterCodeTable.addCode(callRP);
            InterCodeTable.nowVar = res;
        }
        return InterCodeTable.nowVar;
    }

    @Override
    public void tofuncRP() {
        if (this.primtype == 2) {
            int nowindex = InterCodeTable.regindex;
            String ident = func.findFirst().getContent();
            Symbal funcs = InterCodeTable.getSymbalTable().findSymbal(ident);
            ident = funcs.getMipsName();
            String res = "$void";
            CallRP callRP;
            callRP = new CallRP(ident);
            if (func.getNodes().get(2) instanceof FuncRParams) {
                FuncRParams funcRParams = (FuncRParams) func.getNodes().get(2);
                int expcount = funcRParams.getNodes().size() / 2 + 1;
                for (int i = 0; i < expcount; i++) {
                    Exp para = (Exp) funcRParams.getNodes().get(2 * i);
                    para.tointerRP();
                    callRP.addPara(InterCodeTable.nowVar);
                }
            }
            InterCodeTable.addCode(callRP);
            InterCodeTable.nowVar = res;
            InterCodeTable.regindex = nowindex;
        }
    }
}
